package net.projects.pro3_xunlei;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Logger;

public class Xunlei {
    private static final Logger log = Logger.getLogger(Xunlei.class.getName());
    private static AtomicLong fileDownLoadSize = new AtomicLong(0L);
//    private static long fileDownLoadSize=0;

    public static void main(String[] args) {
        String url = "http://www.hostbuf.com/downloads/finalshell_install.exe";

        // 获取文件大小
        final long[] fileSize = {getDownLoadFileSize(url)};
        log.info("待下载的文件大小为" + fileSize[0]);

        // 新文件保存的位置
        String newFile = getFilename(url);
        log.info("新文件的名字为:" + newFile);
        String downloadPath = "Files/" + newFile;

        log.info("新文件的保存路径为:" + downloadPath);

        // 创建新文件
        try {
            RandomAccessFile rag = new RandomAccessFile(downloadPath, "rw");
            rag.setLength(fileSize[0]);
            rag.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 开始下载

        long start = System.currentTimeMillis();
        // 线程池的核心线程数
        int core=Runtime.getRuntime().availableProcessors();
        // 线程池的最大线程数(设置为核心数的两倍)
        int maximum=core*2;
        log.info("线程池的核心线程数为:"+core);
        log.info("线程池的最大线程数为:"+maximum);
        CountDownLatch latch = new CountDownLatch(core);
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(
                core, maximum, 10,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(40),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        for (int i = 0; i < core; i++) {
            long startPos = i * fileSize[0] / core;
            long endPos = (i + 1) * fileSize[0] / core - 1;
            if (i == core-1) {
                endPos = fileSize[0] - 1;
            }
            DownLoadSizeNotify dlsn = new DownLoadSizeNotify() {
                @Override
                public void notifySize(long size) {
                    //6586ms
                    fileDownLoadSize.addAndGet(size);
                    System.out.println("已下载的文件的大小" + fileDownLoadSize.get());

                    //8055ms
//                    synchronized (Xunlei.class){
//                        fileDownLoadSize+=size;
//                        System.out.println("已下载的文件的大小" + fileDownLoadSize);
//                    }
                }
            };
            tpe.execute(new DownLoadTask(url, startPos, endPos, downloadPath, dlsn, latch));
        }

        tpe.shutdown();
        try {
            latch.await(); // 等待所有线程完成
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
        long end = System.currentTimeMillis();
        System.out.println("运行时间：" + (end - start) + "ms");
    }

    private static String getFilename(String url) {
        String[] parts = url.split("/");
        String uuid = UUID.randomUUID().toString().replace("-", "");
        return uuid+parts[parts.length - 1];
    }

    private static long getDownLoadFileSize(String url) {
        long fileSize = 0;
        try {
            URL url1 = new URL(url);
            URLConnection urlConnection = url1.openConnection();
            fileSize = urlConnection.getContentLengthLong();
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return fileSize;
    }
}

interface DownLoadSizeNotify {
    void notifySize(long size);
}
